﻿using EquipmentAlarmSystem.Service.ContentPushUnit;
using EquipmentAlarmSystem.Service.EquipmentCommunicationUnit;
using EquipmentAlarmSystem.Service.Library;
using EquipmentAlarmSystem.Service.Models;
using EquipmentAlarmSystem.Service.Models.Enum;
using System.Text.Json;

namespace EquipmentAlarmSystem.Service.OperationManagementUnit;

/// <summary>
/// 运行管理单元
/// </summary>
public class Management
{
    /// <summary>
    /// 在运行服务id
    /// </summary>
    private static List<string> runningServicesId = new();
    public static List<string> RunningServicesId
    {
        get
        {
            return runningServicesId;
        }
    }

    /// <summary>
    /// 日志记录
    /// </summary>
    static Logging logging = new("Management");

    /// <summary>
    ///  激活设备服务
    /// </summary>
    public string ActivateDeviceService(string id)
    {
        string conf = Basics.GetEquipmentConfiguration(id);

        if (conf == "配置文件不存在")
        {
            return "配置文件不存在";
        }

        try
        {
            //配置文件序列化
            DeviceInformation deviceInformation = JsonSerializer.Deserialize<DeviceInformation>(conf);
            //检查是否在运行
            if (runningServicesId.Contains(deviceInformation.Id) == false)
            {
                //添加设备id
                runningServicesId.Add(deviceInformation.Id);
                //开启新线程
                new Task(() =>
                {
                    if (deviceInformation.Protocol == Protocol.S7)
                    {
                        StartDeviceServices(new EquipmentCommunicationUnit.Siemens.S7(JsonSerializer.Deserialize<DeviceInformationSiemensS7>(conf)));
                    }
                    else if (deviceInformation.Protocol == Protocol.ModbusTcp)
                    {
                        StartDeviceServices(new EquipmentCommunicationUnit.Modbus.Tcp(JsonSerializer.Deserialize<DeviceInformationModusTcp>(conf)));
                    }
                    else
                    {

                    }
                    logging.Info($"{deviceInformation.Name} 远程报警已关闭");

                }).Start();

                return $"{deviceInformation.Name} 远程报警启动中";
            }
            return $"{deviceInformation.Name} 远程报警已经开启，无需重复启动";
        }
        catch (Exception ex)
        {
            return ex.Message;
        }
    }

    /// <summary>
    ///  结束设备服务
    /// </summary>
    public static void EndDeviceService(string id)
    {
        runningServicesId?.Remove(id);
    }

    /// <summary>
    /// 服务线程
    /// </summary>
    /// <param name="communication"></param>
    private void StartDeviceServices(ICommunication communication)
    {
        try
        {
            //连接设备
            communication.Open();
            logging.Info($"{communication.Information.Name} 远程报警已开启");
            //报警地址列表
            SortedList<string, FaultInformation> AlarmList = new();
            //循环采集数据
            while (runningServicesId.Contains(communication.Information.Id))
            {
                SortedList<string, FaultInformation> TemporaryAlarmList = new();

                //获取当前时间的时间戳（秒为单位）  
                long timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
                //获取报警状态
                bool readStatus = communication.AlarmReading(out List<PointInformation> result, out bool isReconnection, out string content);
                //报警读取成功
                if (readStatus)
                {
                    try
                    {
                        #region
                        //报警点位数据处理
                        if (result is not null)
                        {
                            //检查本次报警
                            foreach (var item in result)
                            {
                                //报警已经存在
                                if (AlarmList.ContainsKey(item.Address))
                                {
                                    //报警间隔 是否超时 超时再次发送 刷新等级
                                    var alarmRecords = AlarmList[item.Address];

                                    if (alarmRecords.StartTimestamp <= timestamp)
                                    {
                                        if (alarmRecords.Count % 3 == 0)
                                        {
                                            SendMessage.Receive(communication.Information, item.Content, UserLevel.Administrators);
                                        }
                                        else
                                        {
                                            SendMessage.Receive(communication.Information, item.Content, UserLevel.User);
                                        }
                                        alarmRecords.Count++;
                                        alarmRecords.StartTimestamp = timestamp + Basics.Config.PushInterval;
                                        //刷新数据
                                        AlarmList[item.Address] = alarmRecords;
                                    }
                                    TemporaryAlarmList[item.Address] = alarmRecords;
                                }
                                else //不存在
                                {
                                    //发送数据
                                    SendMessage.Receive(communication.Information, item.Content, UserLevel.User);
                                    TemporaryAlarmList.Add(item.Address, new()
                                    {
                                        Count = 2,
                                        StartTimestamp = timestamp + Basics.Config.PushInterval,
                                    });
                                }
                            }
                        }
                        else
                        {
                            //清除过期报警数据
                            if (AlarmList.Count >= 1)
                            {
                                foreach (var item in AlarmList.Keys)
                                {
                                    if (AlarmList[item].StartTimestamp > timestamp)
                                    {
                                        TemporaryAlarmList.Add(item, AlarmList[item]);
                                    }
                                }
                            }
                        }
                        //
                        AlarmList = TemporaryAlarmList;
                        #endregion
                    }
                    catch (Exception ex)
                    {
                        logging.Warning($"报警历史处理错误： {ex.Message}");
                    }
                }
                else
                {
                    //是否需要断线重连
                    if (isReconnection)
                    {
                        logging.Warning($"{communication.Information.Id};{communication.Information.Name};尝试断线重连！");
                        StartDeviceServices(communication);
                    }
                    else
                    {
                        //logging.Warning($"{communication.Information.Id};{communication.Information.Name};{content}");
                        throw new(content);
                    }
                }

                Thread.Sleep(Basics.Config.SamplingInterval * 1000);
            }
            //结束 关闭连接
            communication.Close();
        }
        catch (Exception ex)
        {
            //关闭连接
            communication.Close();
            runningServicesId!?.Remove(communication.Information.Id);
            logging.Warning(ex.Message);
        }
    }
}
